package fr.uparis10.miage.m1p1.config;

import java.text.DateFormat;
import java.text.ParseException;
import java.util.Calendar;
import java.util.Date;
import java.util.Properties;
import java.util.logging.Level;
import java.util.logging.Logger;

import fr.uparis10.miage.m1p1.global.LogFactory;

public abstract class PropertyReader {
	protected Logger log = LogFactory.getInstance().getLogger(PropertyReader.class.getName());
	
	
	/**
	 * Gets a String property from a Properties object.
	 * If the property is null (doesn't exist), the default value is returned.
	 * 
	 * @param prop - the Properties object
	 * @param key - what to get?
	 * @param defValue - default value in case the property is not defined
	 * @return
	 */
	protected String getStringProperty(Properties prop, String key,
			String defValue) {
		String result = prop.getProperty(key);
		if (result == null) {
			log.log(Level.WARNING, "Invalid value of " + key);
			result = defValue;
		}
		return result;
	}

	/**
	 * Gets a property from a Properties object and converts it to 'int'.
	 * If the conversion fails, a default value is returned.
	 * 
	 * @param prop - the Properties object
	 * @param key - what to get?
	 * @param defValue - default value in case the property is not defined
	 * @return
	 */
	protected int getIntProperty(Properties prop, String key, int defValue) {
		int result;
		try {
			Object tmp = prop.get(key);
			result = Integer.parseInt(tmp.toString());
		} catch (NullPointerException exc) {
			log.log(Level.WARNING, "Unspecified " + key);
			result = defValue;
		} catch (NumberFormatException exc) {
			log.log(Level.WARNING, "Invalid value of " + key);
			result = defValue;
		}
		return result;
	}

	/**
	 * Gets a property from a Properties object and converts it to 'long'.
	 * If the conversion fails, a default value is returned.
	 * 
	 * @param prop - the Properties object
	 * @param key - what to get?
	 * @param defValue - default value in case the property is not defined
	 * @return
	 */
	protected long getLongProperty(Properties prop, String key, long defValue) {
		long result;
		try {
			Object tmp = prop.get(key);
			result = Long.parseLong(tmp.toString());
		} catch (NullPointerException exc) {
			log.log(Level.WARNING, "Unspecified " + key);
			result = defValue;
		} catch (NumberFormatException exc) {
			log.log(Level.WARNING, "Invalid value of " + key);
			result = defValue;
		}
		return result;
	}

	/**
	 * Gets a property from a Properties object and parses it to a 'Date'.
	 * If the conversion fails, a default value is returned.
	 * 
	 * @param prop - the Properties object
	 * @param key - what to get?
	 * @param format - the date format
	 * @param defValue - default value in case the property is not defined
	 * @return
	 */
	protected Date getDateProperty(Properties prop, String key,
			DateFormat format, Date defValue) {
		Date result;
		try {
			Object tmp = prop.get(key);
			result = format.parse(tmp.toString());
		} catch (NullPointerException exc) {
			log.log(Level.WARNING, "Unspecified " + key);
			result = defValue;
		} catch (ParseException exc) {
			log.log(Level.WARNING, "Invalid value of " + key);
			result = defValue;
		}
		return result;
	}

	/**
	 * Gets a property from a  object and parses it to a 'Date'.
	 * If the conversion fails, the system date&time is returned.
	 * 
	 * @param prop - the Properties object
	 * @param key - what to get?
	 * @param format - the date format
	 * @return
	 */
	protected Date getDateProperty(Properties prop, String key, DateFormat format) {
		Date result;
		try {
			Object tmp = prop.get(key);
			result = format.parse(tmp.toString());
		} catch (NullPointerException exc) {
			log.log(Level.WARNING, "Unspecified " + key);
			result = Calendar.getInstance().getTime();
		} catch (ParseException exc) {
			log.log(Level.WARNING, "Invalid value of " + key);
			result = Calendar.getInstance().getTime();
		}
		return result;
	}

	/**
	 * Gets a property from a Properties object and converts it to 'double'.
	 * If the conversion fails, a default value is returned.
	 * 
	 * @param prop - the Properties object
	 * @param key - what to get?
	 * @param defValue - default value in case the property is not defined
	 * @return
	 */
	protected double getDoubleProperty(Properties prop, String key,
			double defValue) {
		double result;
		try {
			Object tmp = prop.get(key);
			result = Double.parseDouble(tmp.toString());
		} catch (NullPointerException exc) {
			log.log(Level.WARNING, "Unspecified " + key);
			result = defValue;
		} catch (NumberFormatException exc) {
			log.log(Level.WARNING, "Invalid value of " + key);
			result = defValue;
		}
		return result;
	}

	/**
	 * Gets a property from a Properties object and converts it to 'float'.
	 * If the conversion fails, a default value is returned.
	 * 
	 * @param prop - the Properties object
	 * @param key - what to get?
	 * @param defValue - default value in case the property is not defined
	 * @return
	 */
	protected float getFloatProperty(Properties prop, String key,
			float defValue) {
		float result;
		try {
			Object tmp = prop.get(key);
			result = Float.parseFloat(tmp.toString());
		} catch (NullPointerException exc) {
			log.log(Level.WARNING, "Unspecified " + key);
			result = defValue;
		} catch (NumberFormatException exc) {
			log.log(Level.WARNING, "Invalid value of " + key);
			result = defValue;
		}
		return result;
	}

}
